#!/usr/bin/env python
import os,commands,re,sys
import xml.dom.minidom

OK=0
WARN=1
CRITICAL=2
UNKNOWN=3

#BOINC do not use more than 75% of the CPU Cores
MemThres=0.1
SwapThres=80

Job_Core=2
total_core=commands.getoutput("cat /proc/cpuinfo |grep processor|wc -l")
LoadThres=3*float(total_core)
CoreThres=0.5
leave_in_memory=0

gp_file="/opt/BOINC/global_prefs.xml"
cs_file="/opt/BOINC/client_state.xml"
gp=xml.dom.minidom.parse(gp_file).firstChild
cs=xml.dom.minidom.parse(cs_file).firstChild
host_venue="home"
projects=cs.getElementsByTagName("project")
for p in projects:
  m=p.getElementsByTagName("project_name")[0].firstChild.data
  if m=="LHC@home":
      try:
        host_venue=p.getElementsByTagName("host_venue")[0].firstChild.data
        break
      except:
        host_venue="None"
  #print "host_venue is ", host_venue
if host_venue=="None":
  max_ncpus_pct=gp.getElementsByTagName("max_ncpus_pct")[0].firstChild.data
  leave_in_memory=gp.getElementsByTagName("leave_apps_in_memory")[0].firstChild.data
  CoreThres=float(max_ncpus_pct)/100
else:
  venues=gp.getElementsByTagName("venue")
  for v in venues:
    if v.getAttribute("name")==host_venue:
      max_ncpus_pct=v.getElementsByTagName("max_ncpus_pct")[0].firstChild.data
      leave_in_memory=v.getElementsByTagName("leave_apps_in_memory")[0].firstChild.data
      CoreThres=float(max_ncpus_pct)/100
      break

result={}
result['CPU']={}
result['CPU']['OK']=1
result['CPU']['msg']=""

#r,o=commands.getstatusoutput("""ps -e -o "cmd"|grep wrapper_|grep -v grep|awk 'BEGIN{total=0}{total+=$5}END{print total}'""")
#if r==0 and o.isdigit():
#  used_core=int(o)
#  ocu_perc=used_core/float(total_core)
  #print "used_core is %s, total_core is %s"%(used_core,total_core)
#  if ocu_perc>CoreThres:
#    result['CPU']['OK']=0
#    result['CPU']['msg']+="BOINC task uses %s CPU|"%ocu_perc

r,o=commands.getstatusoutput("/etc/init.d/Boinc_agent show_task|grep Running")
total_running=int(commands.getoutput("ps -ef|grep wrapper_26|grep -v grep|wc -l"))
if r is not 0:
  result['CPU']['OK']=0
  result['CPU']['msg']+="Failed to show BOINC tasks"
else:
  st=re.split("[,|:]",o)
  total_job=int(st[7])
  stuck_job=total_running-total_job
  if stuck_job>0:
    result['CPU']['OK']=0
    result['CPU']['msg']+="Stuck jobs: %s"%stuck_job

result['Mem']={}
result['Mem']['OK']=1
result['Mem']['msg']=""
t=commands.getoutput("free").split("\n")
mem=re.split("\s+",t[1])
swap=re.split("\s+",t[3])
free_mem=float(mem[3])/(1024*1024)
swap_perc=100*float(swap[2])/float(swap[1])
if free_mem<MemThres:
  result['Mem']['OK']=0
  result['Mem']['msg']+="Free Memory is %.2f GB"%free_mem
if swap_perc>SwapThres:
  result['Mem']['OK']=0
  result['Mem']['msg']+="Swap use %.2f%%"%swap_perc

result['Task']={}
result['Task']['OK']=1
if not leave_in_memory:
  suspended_task=int(st[5])
  if suspended_task>0:
    result['Task']['OK']=0
    result['Task']['msg']="%s tasks suspended!"%suspended_task


result['sysload']={}
result['sysload']['OK']=1
sload=os.getloadavg()
ret=map(lambda x: x>LoadThres,sload)
if True in ret:
  result['sysload']['OK']=0
  result['sysload']['msg']="system load is %s"%str(sload)


Failed=0
Msg=""
for k in result.keys():
  if not result[k]['OK']:
    Failed=1
    Msg+="%s failed:%s; "%(k,result[k]['msg'])
  else:
    Msg+="%s is OK; "%(k)

if Failed:
  print Msg  
  sys.exit(CRITICAL)
else:
  print Msg  
  sys.exit(OK)
